package com.atguigu.tingshu.search.service.impl;

import com.atguigu.tingshu.search.service.LockService;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

/**
 * Author:huzhongkui
 * Date: 2025-03-22 星期六 13:49:46
 * Description:
 */

@Service
public class LockServiceImpl implements LockService {


    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private RedissonClient redissonClient;

    @Override
    public synchronized void testLocalLock() {
        String num = redisTemplate.opsForValue().get("num");

        if (StringUtils.isEmpty(num)) {
            return;
        }

        int i = Integer.parseInt(num);


        redisTemplate.opsForValue().set("num", String.valueOf(++i));

    }

    @Override
    public void testDistroLock() {

        Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent("lock", "1");
        if (aBoolean) {
            String num = redisTemplate.opsForValue().get("num");
            int i = Integer.parseInt(num);
            redisTemplate.opsForValue().set("num", String.valueOf(++i));
            redisTemplate.delete("lock");
        } else {
            testDistroLock();
        }


    }

    @Override
    public void testDistroLockByRedisson() {
        // 1.获取锁对象
        RLock rLock = redissonClient.getLock("abc");

//        rLock.lock();// 分布式锁 自带锁的续期：底层使用可定时任务的线程池，提交了续期任务：每隔10s钟都将指定的key 续期到30s(看门狗)
//        try {
//            System.out.println("xxxx");
//            int i = 1 / 0;
//        } finally {
//            rLock.unlock();  // 只要unlock就不会续期
//        }

//
//        rLock.lock(10, TimeUnit.SECONDS);// 不带续期的 锁到了10s之后自动过期
//        try {
//            System.out.println("xxxx");
//            try {
//                Thread.sleep(10000);
//            } catch (InterruptedException e) {
//                throw new RuntimeException(e);
//            }
//        } finally {
//            rLock.unlock();  // 只要unlock就不会续期
//        }


//        boolean b = rLock.tryLock();  // （锁拥有续期功能） 很像setIfAbSent 不会阻塞抢不到锁的线程未来可以对抢不到锁的线程做其他业务处理
//        if(b){
//            System.out.println("xxxx");
//        }else{
//            System.out.println("yyyy");
//        }

//        boolean b = false;
//        try {
//            b = rLock.tryLock(10, TimeUnit.SECONDS);  // 【没有自动续期功能】如果传入一个时间参数和时间单位 意思指的是 抢不到锁的线程会在这个地方阻塞一段指定的时间  如果在它阻塞期间 另外一个抢到锁线程将锁释放了 那么这个线程等指定的时候之后 直接抢锁成功 反之才抢锁失败
//        } catch (InterruptedException e) {
//            throw new RuntimeException(e);
//        }
//        if (b) {
//            // 抢到锁
//            System.out.println("xxx");
//        } else {
//            System.out.println("yyyyy");
//        }

//        try {
//            boolean b = rLock.tryLock(10, 20, TimeUnit.SECONDS);  //【没有续期功能：抢不到锁的线程阻塞一段时间 && 并且锁到了指定时间自动释放 不会出现续期】
//            if (b) {
//                // 抢到锁
//                System.out.println("xxx");
//            } else {
//                System.out.println("yyyyy");
//            }
//        } catch (InterruptedException e) {
//            throw new RuntimeException(e);
//        }


        boolean b = rLock.tryLock();

        if(b){
            System.out.println("xxx");
            try {
                Thread.sleep(300000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }else{
            System.out.println("yyyy");
        }




    }
}
